package procsim;

public class Adder implements Element{
    private MSignal inSigA, inSigB, result;
    private int numOfBits;

    public Adder(int num){
        numOfBits=num;
    }

    public Adder(int num, MSignal a, MSignal b){
        numOfBits=num;
        if(a!=null) a.addElement(this);
        if(b!=null) b.addElement(this);
        inSigA = a;
        inSigB = b;
    }

    public Adder setA(MSignal sig){
        if(sig!=null) sig.addElement(this);
        inSigA = sig;
        return this;
    }

    public Adder setB(MSignal sig){
        if(sig!=null) sig.addElement(this);
        inSigB = sig;
        return this;
    }

    @Override
    public MSignal result(){
        return result;
    }

    public Adder setResult(MSignal sig){
        result=sig;
        return this;
    }

    @Override
    public Adder tick(){
        int res[] = new int[numOfBits];
        int arr1[] = Util.reverseIntArray(Util.signalArray2IntArray(inSigA.getBits()));
        int arr2[] = Util.reverseIntArray(Util.signalArray2IntArray(inSigB.getBits()));
        int carry = 0;
        for(int i=numOfBits-1; i>=0; i--){
            int tmp=arr1[i]+arr2[i]+carry;
            res[i]=tmp & 1; // vadimo najnizi bit
            carry=(tmp & 2)>>1; // vadimo drugi bit
        }
        if(result!=null) result.set(new MSignal(numOfBits, Util.binaryArray2Int(Util.reverseIntArray(res))));
        return this;
    }

    @Override
    public String toString(){
        return ""+result;
    }

    @Override public void updateSignal(Sig sig){
        boolean changed = false;
        if(inSigA!=null && inSigA==sig){
            inSigA.set(sig.get(), false);
            changed = true;
        }
        if(inSigB!=null && inSigB==sig){
            inSigB.set(sig.get(), false);
            changed = true;
        }
        if(changed) tick();
    }

}
